package com.emm.yixun.website.listeners;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.apache.commons.lang3.StringUtils;
import com.emm.yixun.common.enums.ProcessTypeEnums;
import com.emm.yixun.common.enums.ResponseEnums;
import com.emm.yixun.common.model.ActcommitLog;
import com.emm.yixun.common.model.BusinessAbnorma;
import com.emm.yixun.common.model.PayDeposit;
import com.emm.yixun.common.model.Signed;
import com.emm.yixun.common.model.User;
import com.emm.yixun.common.model.dto.ActcommitLogDto;
import com.emm.yixun.common.model.dto.BusinessAbnormaDto;
import com.emm.yixun.common.model.dto.NoticeEntity;
import com.emm.yixun.common.model.dto.PayDepositDto;
import com.emm.yixun.common.model.dto.ProjectRoomDto;
import com.emm.yixun.common.model.dto.SignedDto;
import com.emm.yixun.common.model.enums.AuditStatusEnum;
import com.emm.yixun.common.model.enums.BusinessTypeEnum;
import com.emm.yixun.common.model.enums.RoomStatusEnum;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.customer.service.PayDepositServiceFacade;
import com.emm.yixun.customer.service.SendMessageServiceFacade;
import com.emm.yixun.customer.service.SignedServiceFacade;
import com.emm.yixun.estate.service.ProjectRoomServiceFacade;
import com.emm.yixun.estate.service.ProjectSettingServiceFacade;
import com.emm.yixun.marketing.service.BusinessAbnormaServiceFacade;
import com.emm.yixun.system.service.UserServiceFacade;
import com.emm.yixun.system.service.notice.signed.SignedDiscountNoticeFacade;
import com.emm.yixun.website.common.utils.SpringWebContextUtil;
import com.emm.yixun.website.service.ActivitiProcessServiceImpl;
import com.emm.yixun.website.service.system.log.ActCommitLogService;

public class SignedDiscountListeners implements Serializable, ExecutionListener{
	private static final long serialVersionUID = 5304231329519610864L;

	@Override
	public void notify(DelegateExecution execution) throws Exception {
		String id=execution.getProcessBusinessKey();
		String processInstanceId=execution.getProcessInstanceId();
		SignedServiceFacade signedServiceFacade=getSignedServiceFacade();
		Response<Signed> signedResponse=signedServiceFacade.findById(Long.valueOf(id));
		if(!signedResponse.isSuccess()){
			throw new Exception("签约记录不存在");
		}
		Signed signed=signedResponse.getEntity();
		if(null==signed){
			throw new Exception("签约记录不存在");
		}
		Long projectId=signed.getProjectId();
        if(null==projectId){
            throw new Exception("项目不存在!");
        }
		if(getActivitiProcessServiceImpl().isCheckPass(processInstanceId)){
			/**
			 * 1.修改签约折扣审核状态为通过   
			 * 2.发起签约审批
			 */
            String startProcessKey= getActivitiProcessServiceImpl().getProcessKey(signed.getMerchantId(),projectId,ProcessTypeEnums.PROCESS_KEY_12);
            if(StringUtils.isEmpty(startProcessKey)){
            	throw new Exception("项目未设置签约审批流程,请去项目流程菜单配置！");
            }
            
			BusinessAbnormaDto queryDto=new BusinessAbnormaDto();
			queryDto.setBusinessId(signed.getId());
			queryDto.setBusinessType(BusinessTypeEnum.SIGNED.getNo());
			queryDto.setProcInstId(processInstanceId);
			ResponseList<BusinessAbnorma> responseList=getBusinessAbnormaServiceFacade().findByDto(queryDto);
			if(null!=responseList && null!=responseList.getEntity() && responseList.getEntity().size()>0){
				BusinessAbnorma businessAbnorma=responseList.getEntity().get(0);
				
				boolean flag = checkAuditCommit(businessAbnorma);
				if(!flag) {
					throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
				}
				
				BusinessAbnormaDto updateBADto=new BusinessAbnormaDto();
				updateBADto.setId(businessAbnorma.getId());
				updateBADto.setCheckDate(new Date());
				updateBADto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				getBusinessAbnormaServiceFacade().updateByPrimaryKey(updateBADto, true);
			}
		    
			User user = getUserServiceFacade().findById(signed.getCreateUserId()).getEntity();
			Map<String, Object> variables = new HashMap<String, Object>();
			getIdentityService().setAuthenticatedUserId(user.getUserAccount());
			//启动签约流程
			String pid=geSendMessageServiceFacade().startDiscountProcessInstance(signed.getMerchantId(),projectId, startProcessKey, signed.getId().toString(), variables);
			SignedDto updateSubscribeDto=new SignedDto();
			updateSubscribeDto.setId(signed.getId());
			updateSubscribeDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
			updateSubscribeDto.setProcInstId(pid);
			Response<Integer> response=signedServiceFacade.updateByPrimaryKey(updateSubscribeDto, true);
			if(!response.isSuccess()){
				throw new Exception("签约审核状态修改错误");
			}
			
			/**
			 * （签约折扣审核通过）推送消息到app
			 * @author ny
			 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(signed.getId());
			noticeEntity.setNoticeType("7");
			noticeEntity.setProcessInstanceId(processInstanceId);
			noticeEntity.setAudStatus("3");
			getSignedDiscountNoticeFacade().createSignedDiscountNotice(noticeEntity);
		}else{
			/**
			 * 1.修改认购折扣审核状态为不通过
			 * 2.修改房源状态为未售或者认筹
			 */
			
			BusinessAbnormaDto queryDto=new BusinessAbnormaDto();
			queryDto.setBusinessId(signed.getId());
			queryDto.setBusinessType(BusinessTypeEnum.SIGNED.getNo());
			queryDto.setProcInstId(processInstanceId);
			ResponseList<BusinessAbnorma> responseList=getBusinessAbnormaServiceFacade().findByDto(queryDto);
			if(null!=responseList && null!=responseList.getEntity() && responseList.getEntity().size()>0){
				BusinessAbnorma businessAbnorma=responseList.getEntity().get(0);
				
				boolean flag = checkAuditCommit(businessAbnorma);
				if(!flag) {
					throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
				}
				
				BusinessAbnormaDto updateBADto=new BusinessAbnormaDto();
				updateBADto.setId(businessAbnorma.getId());
				updateBADto.setAuditStatus(AuditStatusEnum.REJECT.getNo());
				updateBADto.setCheckDate(new Date());
				Response<Integer> businessResponse= getBusinessAbnormaServiceFacade().updateByPrimaryKey(updateBADto, true);
				if(!businessResponse.isSuccess()){
					throw new Exception("签约折扣审核状态修改错误");
				}
			}

			//房源状态为未售或者认筹
			ProjectRoomDto projectRoomDto=new ProjectRoomDto();
			projectRoomDto.setId(signed.getRoomId());
			if(null==signed.getSubscribeId() && null==signed.getPayDepositId()){
				projectRoomDto.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());
			}else if(null!=signed.getSubscribeId()){
				projectRoomDto.setRoomStatus(RoomStatusEnum.BUY.getNo());
			}else if(null!=signed.getPayDepositId()){
				PayDepositDto payDepositDto = new PayDepositDto();
				payDepositDto.setM_auditStatus(" and t.audit_status in (1,3)");
				payDepositDto.setRoomId(signed.getRoomId());
				ResponseList<PayDeposit> payDepositList = getPayDepositServiceFacade().findByDtoJ(payDepositDto);
				if(payDepositList.getEntity()==null||payDepositList.getEntity().size()==0){
					projectRoomDto.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());
				}else{
					projectRoomDto.setRoomStatus(RoomStatusEnum.RESERVE.getNo());
				}
			}
			getProjectRoomServiceFacade().updateByPrimaryKey(projectRoomDto, true);
			
			//签约审核状态改为‘退回’
			SignedDto updateSubscribeDto=new SignedDto();
			updateSubscribeDto.setId(signed.getId());
			updateSubscribeDto.setAuditStatus(AuditStatusEnum.REJECT.getNo());
			updateSubscribeDto.setCheckDate(new Date());
			signedServiceFacade.updateByPrimaryKey(updateSubscribeDto, true);
			
			/**
			 * （签约折扣审核不通过）推送消息到app
			 * @author ny
			 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(signed.getId());
			noticeEntity.setNoticeType("7");
			noticeEntity.setProcessInstanceId(processInstanceId);
			noticeEntity.setAudStatus("2");
			getSignedDiscountNoticeFacade().createSignedDiscountNotice(noticeEntity);
		}
	}
	
	/**
	 * 前置判断,审核记录是否已经提交,防止重复提交
	 * 产生原因: 提交审核,后台处理中时,刷新页面再次提交审核,会重复
	 * true: 可继续执行
	 * false: 不可执行
	 */
	public boolean checkAuditCommit(BusinessAbnorma entity) {
		// 业务数据为null时,默认通过.为了不改变老业务,不影响流程正常行走
		if (null == entity) {
			return true;
		}
		return getActcommitLogService().checkActCommit(entity.getAuditStatus(), entity.getMerchantId(), entity.getId(),
				entity.getProcInstId(), "签约折扣", "PC");
	}
	
	private ActCommitLogService getActcommitLogService(){
		return (ActCommitLogService)SpringWebContextUtil.getApplicationContext().getBean("actCommitLogService");
	}
	
	private PayDepositServiceFacade getPayDepositServiceFacade(){
		return (PayDepositServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("payDepositServiceFacade");
	}
	
	private SignedDiscountNoticeFacade getSignedDiscountNoticeFacade(){
		return (SignedDiscountNoticeFacade)SpringWebContextUtil.getApplicationContext().getBean("signedDiscountNoticeFacade");
	}
	
	private BusinessAbnormaServiceFacade getBusinessAbnormaServiceFacade(){
		return (BusinessAbnormaServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("businessAbnormaServiceFacade");
	}
	
	private ProjectRoomServiceFacade getProjectRoomServiceFacade(){
		return (ProjectRoomServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("projectRoomServiceFacade");
	}
	
	@SuppressWarnings("unused")
	private ProjectSettingServiceFacade getProjectSettingServiceFacade(){
		return (ProjectSettingServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("projectSettingServiceFacade");
	}
	private SignedServiceFacade getSignedServiceFacade(){
		return (SignedServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("signedServiceFacade");
	}
	
	private ActivitiProcessServiceImpl getActivitiProcessServiceImpl(){
		return (ActivitiProcessServiceImpl)SpringWebContextUtil.getApplicationContext().getBean("activitiProcessServiceImpl");
	}
	
	private IdentityService getIdentityService(){
		return (IdentityService)SpringWebContextUtil.getApplicationContext().getBean("identityService");
	}
	
	
	@SuppressWarnings("unused")
	private RuntimeService getRuntimeService(){
		return (RuntimeService)SpringWebContextUtil.getApplicationContext().getBean("runtimeService");
	}
	
	
	private UserServiceFacade getUserServiceFacade() {
		return (UserServiceFacade) SpringWebContextUtil
				.getApplicationContext().getBean("userServiceFacade");
	}
	
	private SendMessageServiceFacade geSendMessageServiceFacade() {
		return (SendMessageServiceFacade) SpringWebContextUtil.getApplicationContext()
				.getBean("sendMessageServiceFacade");
	}
	
	

}
